<?php
/**********************************************************************************
WIKINDX: Bibliographic Management system.
Copyright (C)

This program is free software; you can redistribute it and/or modify it under the terms 
of the GNU General Public License as published by the Free Software Foundation; either 
version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; 
if not, write to the 
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

The WIKINDX Team 2007
sirfragalot@users.sourceforge.net
**********************************************************************************/
/*
* RSS feed
*
* @author Mark Grimshaw
* @version 1
* $Header $
*/
/**
+-------------------------------------+
Based upon work by Laure Endrizzi October 2005
+-------------------------------------+
*/

/***************** START CODE *****************/

include_once("core/sql/SQL.php");
$db = new SQL();
include("./config.php");

// Check we have a sane environment or die
if(!isset($WIKINDX_RSS_LIMIT) || !isset($WIKINDX_RSS_HOST) || !isset($WIKINDX_RSS_BIBSTYLE) || 
	!isset($WIKINDX_RSS_DISPLAY) || !isset($WIKINDX_RSS_TITLE) || !isset($WIKINDX_RSS_DESCRIPTION) || 
	!isset($WIKINDX_RSS_LANGUAGE) || !isset($WIKINDX_RSS_ALLOW))
	die("Missing configuration");

	if(!$WIKINDX_RSS_ALLOW)
		die("Access forbidden");
$channel['title'] = $WIKINDX_RSS_TITLE;
$channel['description'] = $WIKINDX_RSS_DESCRIPTION;
$channel['language'] = $WIKINDX_RSS_LANGUAGE;
$channel['lastBuildDate'] = date("D, d M Y H:i:s T");


if($WIKINDX_RSS_DISPLAY) // display both added and edited resources
	$order = "timestamp";
else // display only added resources.
	$order = "WKX_resource.id";
list($numResults, $item) = queryDb($db, $order, $WIKINDX_RSS_LIMIT, $WIKINDX_RSS_BIBSTYLE);

/** declare text/xml as the header content-type */
header('Content-type: text/xml');
/** print the XML/RSS headers */
print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
print "<rss version=\"2.0\">\n";

/** print channel data */
print "\t<channel>\n";
print "\t\t<title>". $channel['title'] ."</title>\n";
print "\t\t<description>". $channel['description'] ."</description>\n";
print "\t\t<language>". $channel['language'] ."</language>\n";
print "\t\t<lastBuildDate>". $channel['lastBuildDate'] ."</lastBuildDate>\n";

if ($numResults > 0)
{
    for ($i=0;$i<$numResults;$i++) {
        /**
         * loop thru the item array
         * print item data
        */
		$description = FALSE;
        print "\t\t<item>\n";
        if (strlen($item['description'][$i]) > 0) {
            $description .= $item['description'][$i] ." ";
		}
        if (strlen($item['editUser'][$i]) > 0)
		{
            $description .= " [Edited by: " . $item['editUser'][$i] . ']';
			$item['title'][$i] = 'Edited ' . $item['title'][$i];
        }
        else if (strlen($item['addUser'][$i]) > 0)
		{
            $description .= " [Added by: " . $item['addUser'][$i] . ']';
			$item['title'][$i] = 'Added ' . $item['title'][$i];
        }
        if (strlen($item['title'][$i]) > 0) {
            print "\t\t\t<title>". $item['title'][$i] ."</title>\n";
        }
        if (strlen($item['timestamp'][$i]) > 0) {
            print "\t\t\t<pubDate>". $item['timestamp'][$i] ."</pubDate>\n";
        }
        if (strlen($item['link'][$i]) > 0) {
            print "\t\t\t<link>" . $WIKINDX_RSS_HOST . "?method=RSS&amp;action=resourceView&amp;id=" . 
			$item['link'][$i] ."</link>\n";
        }
        print "\t\t\t<description>". $description ."</description>\n";
        print "\t\t</item>\n";
    }
}

print "\t</channel>\n";
print "</rss>\n";

// Function to query the database and return formatted entries
	function queryDb($db, $order, $WIKINDX_RSS_LIMIT, $WIKINDX_RSS_BIBSTYLE)
	{
		$bibStyle = new BIBSTYLE($db, $WIKINDX_RSS_BIBSTYLE);
		$sql = "SELECT `WKX_resource`.`id` AS `resourceId`, `type`, `title`, `subtitle`, `noSort`, `url`, `isbn`, `field1`, `field2`, `field3`, `field4`, `field5`, `field6`, `field7`, `field8`, `field9`, `collection`, `publisher`, `miscField1`, `miscField2`, `miscField3`, `miscField4`, `miscField5`, `miscField6`, `tag`, `addUserIdResource`, `editUserIdResource`, `year1`, `year2`, `year3`, `pageStart`, `pageEnd`, `creator1`, `creator2`, `creator3`, `creator4`, `creator5`, `publisherName`, `publisherLocation`, `publisherType`, `collectionTitle`, `collectionTitleShort`, `collectionType`, `WKX_resource_timestamp`.`timestamp` AS `timestamp` FROM `WKX_resource` LEFT JOIN `WKX_resource_misc` ON `WKX_resource`.`id`=`WKX_resource_misc`.`id` LEFT JOIN `WKX_resource_year` ON `WKX_resource`.`id`=`WKX_resource_year`.`id` LEFT JOIN `WKX_resource_page` ON `WKX_resource`.`id`=`WKX_resource_page`.`id` LEFT JOIN `WKX_resource_creator` ON `WKX_resource`.`id`=`WKX_resource_creator`.`id` LEFT JOIN `WKX_publisher` ON `publisher`=`WKX_publisher`.`id` LEFT JOIN `WKX_collection` ON `collection`=`WKX_collection`.`id` LEFT JOIN `WKX_resource_timestamp` ON `WKX_resource_timestamp`.`id`=`WKX_resource`.`id` ORDER BY " . $order . " DESC ";
		$resultSet = @$db->limit($sql, $WIKINDX_RSS_LIMIT, 0) or die(mysql_error());
		$numResults = $db->numRows($resultSet);
		$x = 0;
		while($list_results = $db->loopRecordSet($resultSet))
		{
			/** construct a hierarchial array for the item node */
			if($list_results['noSort'])
				$item['title'][$x] = htmlspecialchars(stripslashes($list_results['noSort'])) . ' ' . 
				htmlspecialchars(stripslashes($list_results['title']));
			else
				$item['title'][$x] = htmlspecialchars(stripslashes($list_results['title']));
			$item['title'][$x] = htmlspecialchars(stripslashes($list_results['type'])) . ': ' . 
				$item['title'][$x];
			$item['timestamp'][$x] = $list_results['timestamp'];
			list($item['addUser'][$x], $item['editUser'][$x]) = 
				getUser($db, $list_results['addUserIdResource'], $list_results['editUserIdResource']);
			$item['link'][$x] = $list_results['resourceId'];
			$item['description'][$x] = htmlspecialchars($bibStyle->process($list_results));
			$x++;
		}
		return array($numResults, $item);
	}

// Function to grab add/edit full names or, if no full names, the user names.
	function getUser($db, $addId, $editId)
	{
		$userAdd = $userEdit = FALSE;
		if($addId)
		{
			$sql = "SELECT username, fullname FROM WKX_users WHERE WKX_users.id=$addId";
			$query = @$db->query($sql) or die(mysql_error());
			$row = @$db->fetchRow($query);
			if($row['fullname'])
				$userAdd = htmlspecialchars(stripslashes($row['fullname']));
			else if($row['username'])
				$userAdd = htmlspecialchars(stripslashes($row['username']));
			else
				$userAdd = "unknown";
		}
		if($editId)
		{
			$sql = "SELECT username, fullname FROM WKX_users WHERE id=$editId";
			$query = @$db->query($sql)  or die(mysql_error());
			$row = @$db->fetchRow($query);
			if($row['fullname'])
				$userEdit = htmlspecialchars(stripslashes($row['fullname']));
			else if($row['username'])
				$userEdit = htmlspecialchars(stripslashes($row['username']));
			else
				$userEdit = "unknown";
		}
		return array($userAdd, $userEdit);
	}

//Format the item to a bibliographic style
class BIBSTYLE
{
// Constructor
	function BIBSTYLE($db, $WIKINDX_RSS_BIBSTYLE)
	{
		$this->db = $db;
		include_once("core/styles/BIBFORMAT.php");
		$this->bibformat = new BIBFORMAT();
		$this->output = 'plain';
		$this->bibformat->output = 'plain';
// WIKINDX-specific
		$this->bibformat->wikindx = TRUE;
		$this->setupStyle = $WIKINDX_RSS_BIBSTYLE;
		include_once("core/html/MISC.php");
		list($info, $citation, $footnote, $styleCommon, $styleTypes) = 
				$this->bibformat->loadStyle("styles/bibliography/", $this->setupStyle);
		$this->bibformat->getStyle($styleCommon, $styleTypes, $footnote);
		unset($styleCommon, $styleTypes, $footnote);
	}
// Accept a SQL result row of raw bibliographic data and process it.
// We build up the $bibformat->item array with formatted parts from the raw $row
	function process($row, $shortOutput = FALSE)
	{
		$this->row = $row;
		$this->shortOutput = $shortOutput;
		$type = $row['type']; // WIKINDX type
		unset($row);
// For WIKINDX, if type == book or book article and there exists both 'year1' and 'year2' in $row (entered as 
// publication year and reprint year respectively), then switch these around as 'year1' is 
// entered in the style template as 'originalPublicationYear' and 'year2' should be 'publicationYear'.
		if(($type == 'book') || ($type == 'book_article'))
		{
			$year2 = stripslashes($this->row['year2']);
			if($year2 && !$this->row['year1'])
			{
				$this->row['year1'] = $year2;
				unset($this->row['year2']);
			}
			else if($year2 && $this->row['year1'])
			{
				$this->row['year2'] = stripslashes($this->row['year1']);
				$this->row['year1'] = $year2;
			}
		}
		$this->row = $this->bibformat->preProcess($type, $this->row);
// Return $type is the OSBib resource type ($this->book, $this->web_article etc.) as used in STYLEMAP
		$type = $this->bibformat->type;
		$this->preProcess($type);
// We now have an array for this item where the keys match the key names of $this->styleMap->$type 
// where $type is book, journal_article, thesis etc. and are now ready to map this against the defined 
// bibliographic style for each resource ($this->book, $this->book_article etc.).
// This bibliographic style array not only provides the formatting and punctuation for each field but also 
// provides the order. If a field name does not exist in this style array, we print nothing.
		$pString = $this->bibformat->map();
// bibTeX ordinals such as 5$^{th}$
		$pString = preg_replace_callback("/(\d+)\\$\^\{(.*)\}\\$/", array($this, "ordinals"), $pString);
// remove extraneous {...}
		return preg_replace("/{(.*)}/U", "$1", $pString);
	}
// Perform some pre-processing
	function preProcess($type)
	{
// Various types of creator
		for($index = 1; $index <= 5; $index++)
		{
			if($this->shortOutput && ($index > 1))
				break;
			if(!$this->row['creator' . $index] || 
				!array_key_exists('creator' . $index, $this->bibformat->styleMap->$type))
				continue;
			if(array_key_exists('creator' . $index, $this->bibformat->styleMap->$type))
				$this->grabNames('creator' . $index);
		}
// The title of the resource
		$this->createTitle();
		if(!$this->shortOutput)
		{
// edition
			if($editionKey = array_search('edition', $this->bibformat->styleMap->$type))
				$this->createEdition($editionKey);
// pageStart and pageEnd
			$this->pages = FALSE; // indicates not yet created pages for articles
			if(array_key_exists('pages', $this->bibformat->styleMap->$type))
				$this->createPages();
// Date
			if(array_key_exists('date', $this->bibformat->styleMap->$type))
				$this->createDate();
// runningTime for film/broadcast
			if(array_key_exists('runningTime', $this->bibformat->styleMap->$type))
				$this->createRunningTime();
// web_article URL
			if(array_key_exists('URL', $this->bibformat->styleMap->$type) && 
				($itemElement = $this->createUrl()))
				$this->bibformat->addItem($itemElement, 'URL', FALSE);
// proceedings_article can have publisher as well as organiser/location. Publisher is in 'miscField1'
			if(($type == 'proceedings_article') && $this->row['miscField1'])
			{
				$recordset = $this->db->select(array("WKX_publisher"), 
					array("publisherName", "publisherLocation"), 
					" WHERE " . $this->db->formatField('id') . "=" . 
					$this->db->tidyInput($this->row['miscField1']));
				$pubRow = $this->db->fetchRow($recordset);
				if($pubRow['publisherName'])
					$this->bibformat->addItem($pubRow['publisherName'], 'publisher');
				if($pubRow['publisherLocation'])
					$this->bibformat->addItem($pubRow['publisherLocation'], 'location');
			}
// the rest...  All other database resource fields that do not require special formatting/conversion.
			$this->bibformat->addAllOtherItems($this->row);
		}
// Add the publication year for short output.
		else if(array_key_exists('year1', $this->bibformat->styleMap->$type) && $this->row['year1'])
				$this->bibformat->addItem($this->row['year1'], 'year1', FALSE);
	}
// callback for ordinals above
	function ordinals($matches)
	{
		return $matches[1] . $matches[2];
	}
// Create the resource title
	function createTitle()
	{
		$pString = stripslashes($this->row['noSort']) . ' ' . 
			stripslashes($this->row['title']);
		if($this->row['subtitle'])
			$pString .= $this->bibformat->style['titleSubtitleSeparator'] . stripslashes($this->row['subtitle']);
// anything enclosed in {...} is to be left as is 
		$this->bibformat->formatTitle($pString, "{", "}");
	}
// Create the URL
	function createUrl()
	{
		if(!$this->row['url'])
			return FALSE;
		$url = stripslashes($this->row['url']);
		unset($this->row['url']);
		return $url;
	}
// Create date
	function createDate()
	{
		$startDay = isset($this->row['miscField2']) ? stripslashes($this->row['miscField2']) : FALSE;
		$startMonth = isset($this->row['miscField3']) ? stripslashes($this->row['miscField3']) : FALSE;
		unset($this->row['miscField2']);
		unset($this->row['miscField3']);
		$endDay = isset($this->row['miscField5']) ? stripslashes($this->row['miscField5']) : FALSE;
		$endMonth = isset($this->row['miscField6']) ? stripslashes($this->row['miscField6']) : FALSE;
		unset($this->row['miscField5']);
		unset($this->row['miscField6']);
		$startDay = ($startDay == 0) ? FALSE : $startDay;
		$startMonth = ($startMonth == 0) ? FALSE : $startMonth;
		if(!$startMonth)
			return;
		$endDay = ($endDay == 0) ? FALSE : $endDay;
		$endMonth = ($endMonth == 0) ? FALSE : $endMonth;
		$this->bibformat->formatDate($startDay, $startMonth, $endDay, $endMonth);
	}
// Create runningTime for film/broadcast
	function createRunningTime()
	{
		$minutes = stripslashes($this->row['miscField1']);
		$hours = stripslashes($this->row['miscField4']);
		if(!$hours && !$minutes)
			return;
		if(!$hours)
			$hours = 0;
		$this->bibformat->formatRunningTime($minutes, $hours);
	}
// Create the edition number
	function createEdition($editionKey)
	{
		if(!$this->row[$editionKey])
			return FALSE;
		$edition = stripslashes($this->row[$editionKey]);
		$this->bibformat->formatEdition($edition);
	}
// Create page start and page end
	function createPages()
	{
		if(!$this->row['pageStart'] || $this->pages) // empty field or page format already done
		{
			$this->pages = TRUE;
			return;
		}
		$this->pages = TRUE;
		$start = trim(stripslashes($this->row['pageStart']));
		$end = $this->row['pageEnd'] ? trim(stripslashes($this->row['pageEnd'])) : FALSE;
		$this->bibformat->formatPages($start, $end);
	}
// get names from database for creator, editor, translator etc.
	function grabNames($nameType)
	{
		$nameIds = split(",", $this->row[$nameType]);
		foreach($nameIds as $nameId)
			$conditions[] = $this->db->formatField("id") . "=" . $this->db->tidyInput($nameId);
		$recordset = $this->db->select(array("WKX_creator"), array("surname", "firstname", 
			"initials", "prefix", "id"), 
			" WHERE " . join(" OR ", $conditions));
		$numNames = $this->db->numRows($recordset);
// Reorder $row so that creator order is correct and not that returned by SQL
		$ids = explode(",", $this->row[$nameType]);
		while($row = $this->db->loopRecordSet($recordset))
			$rowSql[$row['id']] = $row;
		if(!isset($rowSql))
			return FALSE;
		foreach($ids as $id)
			$rowTemp[] = $rowSql[$id];
		$this->bibformat->formatNames($rowTemp, $nameType);
	}
}
?>